using MediatR;
using S.O.Api.Read.Application.Command.Medical;
using S.O.Domain.Dto.Output;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;
using Microsoft.Extensions.Logging;
using AutoMapper;

namespace S.O.Api.Read.Application.Handler.Medical
{
    /// <summary>
    /// 获取未付费患者列表处理器
    /// 用于门诊收费页面显示需要收费的患者信息
    /// </summary>
    public class GetUnpaidPatientsHandler : IRequestHandler<GetUnpaidPatientsCommand, APIResult<List<UnpaidPatientDto>>>
    {
        /// <summary>
        /// 挂号记录仓储
        /// </summary>
        private readonly IBaseRepository<RegistrationModel> _registrationRepository;
        
        /// <summary>
        /// 患者信息仓储
        /// </summary>
        private readonly IBaseRepository<PatientModel> _patientRepository;
        
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<GetUnpaidPatientsHandler> _logger;
        
        /// <summary>
        /// 对象映射器
        /// </summary>
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="registrationRepository">挂号记录仓储</param>
        /// <param name="patientRepository">患者信息仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetUnpaidPatientsHandler(
            IBaseRepository<RegistrationModel> registrationRepository,
            IBaseRepository<PatientModel> patientRepository,
            IMapper mapper,
            ILogger<GetUnpaidPatientsHandler> logger)
        {
            _registrationRepository = registrationRepository;
            _patientRepository = patientRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取未付费患者列表请求
        /// </summary>
        /// <param name="request">获取未付费患者列表命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>未付费患者列表</returns>
        public Task<APIResult<List<UnpaidPatientDto>>> Handle(GetUnpaidPatientsCommand request, CancellationToken cancellationToken)
        {
            APIResult<List<UnpaidPatientDto>> result = new APIResult<List<UnpaidPatientDto>>();
            
            try
            {
                _logger.LogInformation("开始获取未付费患者列表，页码：{PageIndex}，页大小：{PageSize}", request.PageIndex, request.PageSize);
                
                // 获取所有未删除的挂号记录
                var registrations = _registrationRepository.GetALL().Where(x => x.IsDeleted == false);
                var patients = _patientRepository.GetALL().Where(x => x.IsDeleted == false);
                
                // 构建查询条件：获取已挂号但未付费的患者
                var query = from registration in registrations
                           join patient in patients on registration.PatientId equals patient.Id
                           where registration.IsEnable == true && 
                                 (registration.Status == "已挂号" || registration.Status == "待诊" || registration.Status == "就诊中")
                           select new { registration, patient };
                
                // 应用查询条件
                if (!string.IsNullOrWhiteSpace(request.RegistrationNo))
                {
                    query = query.Where(x => x.registration.RegistrationNo.Contains(request.RegistrationNo));
                }
                
                if (!string.IsNullOrWhiteSpace(request.PatientName))
                {
                    query = query.Where(x => x.patient.PatientName.Contains(request.PatientName));
                }
                
                if (!string.IsNullOrWhiteSpace(request.Department))
                {
                    query = query.Where(x => x.registration.Department.Contains(request.Department));
                }
                
                // 按挂号时间倒序排序并分页
                var results = query
                    .OrderByDescending(x => x.registration.RegistrationDate)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .Select(x => new UnpaidPatientDto
                    {
                        PatientId = x.patient.Id,
                        RegistrationNumber = x.registration.RegistrationNo,
                        Name = x.patient.PatientName,
                        Gender = x.patient.Gender == 1 ? "男" : "女",
                        Department = x.registration.Department,
                        IdCard = x.patient.IdCard,
                        Doctor = x.registration.Doctor,
                        RegistrationDate = x.registration.RegistrationDate,
                        VisitDate = x.registration.VisitDate,
                        Status = x.registration.Status
                    })
                    .ToList();
                
                _logger.LogInformation("成功获取未付费患者列表，共 {Count} 条记录", results.Count);
                
                result.Code = APIEnums.Success;
                result.Msg = "获取成功";
                result.Data = results;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取未付费患者列表时发生异常");
                result.Code = APIEnums.Error;
                result.Msg = "获取未付费患者列表失败";
                result.Data = new List<UnpaidPatientDto>();
            }
            
            return Task.FromResult(result);
        }
    }
}